package com.shhm.common.utils;

import com.alibaba.fastjson2.JSON;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.shhm.common.dto.response.AjaxResultPlus;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.data.redis.core.RedisTemplate;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author JackZ
 * @version 1.0
 * @description: TODO
 * @date 2025/9/18 下午5:01
 */
public class CaptchaUtil {
    public static AjaxResultPlus getCaptcha(
            HttpServletRequest request,
            RedisTemplate<String, Object> redisTemplate,
            DefaultKaptcha kaptchaBeanMath,
            String saveRedisKey
    ) throws IOException {
        //        获取ip
        String ipAddress = IpUtil.getIpAddress(request);
        String key = saveRedisKey + ipAddress;
        if (!Objects.isNull(redisTemplate.opsForValue().get(key))) {
            redisTemplate.delete(key);
        }

//        生成验证码内容
        int num1 = (int)(Math.random() * 10) + 1;
        int num2 = (int)(Math.random() * 10) + 1;
        String code=num1+"+"+num2+"=";
        int ans=num1+num2;

//        生成内存图像
        BufferedImage image=kaptchaBeanMath.createImage(code);

//        设置键(基于IP地址作为键)
        String maxNum = RedisUtil.REDIS_LOGIN_CAPTCHA_RETRY;
        sr_data(redisTemplate,Integer.toString(ans),key,maxNum);

//        将图像转为base64
        String encode = ImageToBase64(image);

        return AjaxResultPlus.custom(200,false).put("data",encode);
    }

    /**
     * redis存储数据
     * @param code
     * @param key
     */
    private static void sr_data(RedisTemplate<String, Object> redisTemplate,String code, String key, String retryNum){
        HashMap<String, Object> rv_data = new HashMap<>();
        rv_data.put("maxRetry",retryNum);
        rv_data.put("code",code);
        redisTemplate.opsForValue().set(key, JSON.toJSONString(rv_data),5, TimeUnit.MINUTES);
    }

    /**
     * 图片转base64
     * @param image
     * @return
     * @throws IOException
     */
    private static String ImageToBase64(BufferedImage image) throws IOException {
        ByteArrayOutputStream outstream = new ByteArrayOutputStream();
        ImageIO.write(image,"jpg",outstream);
        return Base64.getEncoder().encodeToString(outstream.toByteArray());
    }

    /**
     * 查看验证码是否通过
     * @param request
     * @return
     */
    public static String checkCaptcha(HttpServletRequest request,RedisTemplate<String, Object> redisTemplate,Integer codeAns,String saveRedisKey) {
        //        获取ip
        String ipAddress = IpUtil.getIpAddress(request);
        String key = saveRedisKey + ipAddress;
        Object r_data = redisTemplate.opsForValue().get(key);

//        判断是否存在
        if (Objects.isNull(r_data)) return "验证码不存在或已过期!";

//        获取验证码和验证次数
        Map r_d = JSON.parseObject((String) r_data, Map.class);
        String captcha_code = (String)r_d.get("code");
        int r_ans = Integer.parseInt(captcha_code);

        String captcha_num = (String) r_d.get("maxRetry");
        Integer r_cn = Integer.parseInt(captcha_num);

//        判断校验次数过多则销毁该验证码
        if (r_cn==0) {
            redisTemplate.delete(key);
            return "您已多次校验错误，将刷新验证码!";
        }

        //判断验证是否成功
        if (r_ans!=codeAns) {
            r_cn--;
            String r_scn=r_cn.toString();
            sr_data(redisTemplate,captcha_code,key,r_scn);
            return "验证码错误!";
        }

//        通过验证并销毁验证码
        redisTemplate.delete(key);
        return "pass";
    }
}
